// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-9-20

#include "stdafx.h"
#include ".\dragger.h"

//##ModelId=44C4B608001F
class CJoyDraggerFloat : public CJoyWnd
{
public:
    
	//##ModelId=44C4B6080021
    bool Create()
    {
        if(!CreateEx(
            WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
            TOOLTIPS_CLASS,
            //JoyGetManager()->GetWndClass(),
            NULL,
            WS_POPUP,
            CRect(0, 0, 10, 10),
            NULL, 0))
        {
            return false;
        }

        return true;
    }

    DECLARE_MESSAGE_MAP()
	//##ModelId=44C4B608002E
    afx_msg void OnSize(UINT nType, int cx, int cy);
};

BEGIN_MESSAGE_MAP(CJoyDraggerFloat, CJoyWnd)
    ON_WM_SIZE()
END_MESSAGE_MAP()

//##ModelId=44C4B608002E
void CJoyDraggerFloat::OnSize(UINT nType, int cx, int cy)
{
    CJoyWnd::OnSize(nType, cx, cy);

    CRect wr;
    GetWindowRect(&wr);
    CPoint orig(0, 0);
    ClientToScreen(&orig);

    orig.x -= wr.left;
    orig.y -= wr.top;
    HRGN h = CreateRectRgn(orig.x, orig.y, orig.x + cx, orig.y + cy);
    SetWindowRgn(h, TRUE);
}


IMPLEMENT_DYNAMIC(CJoyDragger, CJoyWnd)

//##ModelId=44C4B6050312
CJoyDragger::CJoyDragger(void)
{
    m_align = AT_Right;
    m_attachWnd = NULL;
    m_skinAlign = true;
    m_dragBegin = false;
    m_draggerFloat  = NULL;
    m_dragColor.SetValue(0xFF888888);

    m_moveArea.SetRect(0, 0, 2096, 1536);
    m_floatMargin.SetRect(0, 0, 0, 0);
}

//##ModelId=44C4B6050314
CJoyDragger::~CJoyDragger(void)
{
}

BEGIN_MESSAGE_MAP(CJoyDragger, CJoyWnd)
    ON_WM_CREATE()
    ON_WM_DESTROY()
END_MESSAGE_MAP()

//##ModelId=44C4B60502FD
void CJoyDragger::CM_Drag(const CPoint& )
{
    //if(!m_dragBegin)
    //{
    //    m_dragBegin = true;
    //    m_dragOrig = m_area.TopLeft();
    //    m_origBackColor = m_backColor;
    //    SetBackColor(m_dragColor);
    //}
    //__super::CM_Drag(p);
}

//##ModelId=44C4B60502E3
void CJoyDragger::CM_MouseHover()
{
    __super::CM_MouseHover();
}

//##ModelId=44C4B60502E5
void CJoyDragger::CM_MouseLeave()
{
    __super::CM_MouseLeave();
    m_draggerFloat->SetVisible(false);
    m_dragBegin = false;
}

//##ModelId=44C4B60502EF
void CJoyDragger::CM_Mouse(MouseMessage msg, const CPoint& pt)
{
    __super::CM_Mouse(msg, pt);

    bool vert = true;
    switch(m_align)
    {
    case AT_Top:
    case AT_Bottom:
        vert = false;
        break;
    case AT_Left:
    case AT_Right:
        vert = true;
        break;
    }
    SetCursor(LoadCursor(NULL, vert ? IDC_SIZEWE : IDC_SIZENS));

    if(msg == MM_LeftDown)
    {
        m_dragBegin = true;
        m_dragOrig = pt;
        CRect a(0, 0, m_area.Width(), m_area.Height());
        ClientToScreen(&a);
        m_draggerFloat->SetBackColor(m_dragColor);
        m_draggerFloat->SetArea(a);
        m_draggerFloat->ShowWindow(SW_SHOWNOACTIVATE);
        //m_draggerFloat->SetVisible(true);
        return;
    }
    else if(msg == MM_Move)
    {
        if(!m_draggerFloat->IsVisible())
        {
            return;
        }
        CPoint validPos = m_area.TopLeft()+pt-m_dragOrig;
        if(validPos.x < m_moveArea.left)
        {
            validPos.x = m_moveArea.left;
        }
        else if(validPos.x > m_moveArea.right)
        {
            validPos.x = m_moveArea.right;
        }
        if(validPos.y < m_moveArea.top)
        {
            validPos.y = m_moveArea.top;
        }
        else if(validPos.y > m_moveArea.bottom)
        {
            validPos.y = m_moveArea.bottom;
        }
        CPoint relPos = validPos-m_area.TopLeft();

        CRect a(0, 0, m_area.Width(), m_area.Height());
        ClientToScreen(&a);
        if(vert)
        {
            relPos.y = 0;
        }
        else
        {
            relPos.x = 0;
        }
        a.OffsetRect(relPos);
        if(vert)
        {
            if(a.Width() <= m_floatMargin.Width())
            {
                a.left += a.Width()/2;
                a.top  += m_floatMargin.top;
                a.right-= a.left+1;
                a.bottom-= m_floatMargin.bottom;
            }
            else
            {
                a.left += m_floatMargin.left;
                a.top  += m_floatMargin.top;
                a.right-= m_floatMargin.right;
                a.bottom-= m_floatMargin.bottom;
            }
        }
        else
        {
            if(a.Height() <= m_floatMargin.Height())
            {
                a.left += m_floatMargin.left;
                a.top  += a.Height()/2;
                a.right-= m_floatMargin.right;
                a.bottom-= a.left+1;
            }
            else
            {
                a.left += m_floatMargin.left;
                a.top  += m_floatMargin.top;
                a.right-= m_floatMargin.right;
                a.bottom-= m_floatMargin.bottom;
            }
        }
        CWnd* parent = GetParent();
        if(parent != NULL)
        {          
            CRect redraw = m_draggerFloat->GetArea();
            parent->ScreenToClient(&redraw);
            GetParent()->RedrawWindow(&redraw, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
        }
        m_draggerFloat->SetArea(a);
        m_draggerFloat->RedrawWindow(NULL, NULL, RDW_UPDATENOW);
        
        return;
    }
    else if(msg != MM_LeftUp)
    {
        return;
    }
    if(!m_dragBegin)
    {
        return;
    }
    m_draggerFloat->SetVisible(false);
    m_dragBegin = false;

    if(m_attachWnd == NULL)
    {
        //__super::CM_Drag(p);
        return;
    }
    CJoyWnd* parent = DYNAMIC_DOWNCAST(CJoyWnd, m_attachWnd->GetParent());
    if(parent == NULL)
    {
        //__super::CM_Drag(p);
        return;
    }

    CRect a;
    CPoint validPos = m_area.TopLeft()+pt-m_dragOrig;
    if(validPos.x < m_moveArea.left)
    {
        validPos.x = m_moveArea.left;
    }
    else if(validPos.x > m_moveArea.right)
    {
        validPos.x = m_moveArea.right;
    }
    if(validPos.y < m_moveArea.top)
    {
        validPos.y = m_moveArea.top;
    }
    else if(validPos.y > m_moveArea.bottom)
    {
        validPos.y = m_moveArea.bottom;
    }
    CPoint relPos = validPos-m_area.TopLeft();
    if(vert)
    {
        if(relPos.x == 0)
        {
            return;
        }
    }
    else
    {
        if(relPos.y == 0)
        {
            return;
        }
    }
    a = m_attachWnd->GetArea();
    switch(m_align)
    {
    case AT_Left:
        a.right += relPos.x;
        break;
    case AT_Top:
        a.bottom += relPos.y;
        break;
    case AT_Right:
        a.left += relPos.x;
        break;
    case AT_Bottom:
        a.top += relPos.y;
        break;
    default:
        return;
    }
    m_attachWnd->SetArea(a, FALSE);
    parent->NotifyAlign();
}


//##ModelId=44C4B605031E
int CJoyDragger::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CJoyWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    m_draggerFloat = new CJoyDraggerFloat();
    m_draggerFloat->Create();

    return 0;
}

//##ModelId=44C4B6050321
void CJoyDragger::OnDestroy()
{
    if(m_draggerFloat != NULL)
    {
        m_draggerFloat->Destroy();
        delete m_draggerFloat;
        m_draggerFloat = NULL;
    }
    CJoyWnd::OnDestroy();

}
